package com.asset.action;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.asset.pojo.BranchOffice;
import com.asset.pojo.Department;
import com.asset.pojo.User;
import com.asset.pojo.UserOperate;
import com.asset.utils.*;
import com.asset.webBean.UserWeb;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

public class UserAction extends BaseAction {

	private static final long serialVersionUID = 1L;
	private User user;
	private UserWeb userWeb;
	private UserOperate uote;
	private User loginUser;
	private String fileName;
	private Long id;
	private String name;
	private String password;
	private Short role;
	private String department;
	private String code;
	private Integer branchOfficeId;
	private String remark;
	private Long[] ids;
	private String userRoleKey;
	private String userStatusKey;
	private String opera; // 'add'-添加用户信息，‘modify’-修改用户信息
	private List<User> userList;
	private JSONObject tableData;

	private JSONArray departmentArr;
	private String departQueryName;
	private String loginName;
	
	// 表格查询
	private String queryName;
	private Integer draw;
	private Integer length;
	private Integer start;
	private Date addTime1;
	private Date addTime2;

	private File file;

	// 操作结果信息返回
	private String operationResult;

	// 公司与部门的查询集合
	private List<BranchOffice> branchOfficeList;
	private List<Department> departmentList;

	//得到登录用户
	{
		loginUser = (User) getSession().getAttribute(UserKEY);				
	}
	//用户类型转换
	private UserWeb passUserWeb(User u) {
		UserWeb uw = new UserWeb();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		uw.setId(u.getId());
		uw.setName(u.getName());
		uw.setLoginName(u.getLoginName());
		if (u.getRole() != null) {
			uw.setRole(User.Role.getEnum(user.getRole(), null, null).name());
		}
		uw.setAddedTime(sdf.format(u.getAddedTime()));
		uw.setModifyTime(sdf.format(u.getModifyTime()));
		if (u.getStatus() != null) {
			uw.setStatus(User.Status.getEnum(user.getStatus(), null, null).name());
		}
		uw.setDepartment(user.getDepartment());
		uw.setCode(u.getCode().toString());
		uw.setRemark(u.getRemark());
		return uw;
	}
    
	//用户列表
	public String listUser() {
		try{
			getSession().setAttribute("colId", 3);
			queryName=getQueryName();
			if(getSession().getAttribute("tip") != null && getSession().getAttribute("tip")!=""){
				tip=(String) getSession().getAttribute("tip");
				getSession().setAttribute("tip", "");
			};
		}catch(Exception e){
			e.printStackTrace();
			getSession().setAttribute("e", e.getMessage());
			return "sysError";
		}
		return SUCCESS;
	}
    //添加页面
	public String toAddUser() {
		try {
			user = new User();
			getSession().setAttribute("opteStatus", 0);
			branchOfficeList = branchOfficeService.listBranchOffice(null);
		} catch (Exception e) {
			e.printStackTrace();
			return "sysError";
		}
		
		return SUCCESS;
	}
    //添加用户
	public String addUser() {
			user.setAddedTime(new Date());
			user.setModifyTime(new Date());
			userService.addUser(user);
						
			uote = new UserOperate();
			uote.setOptePerson(loginUser.getName());
			uote.setOpteGenre(UserOperate.OpteGenre.getValue("添加"));
			uote.setUserCode(user.getCode());
			uote.setUserName(user.getName());
			uote.setOpteTime(new Date());
			useropteService.insertUserOpte(uote);
			getSession().setAttribute("tip", "添加成功");
			operationResult = "success";
		return SUCCESS;
	}
	
	//添加时查询登录名和用户编号是否存在
	public String userListDataCheck(){
        int sessStatus =  (int) getSession().getAttribute("opteStatus");
        String sessLoginName = (String) getSession().getAttribute("loginName");
        String sessCode = (String) getSession().getAttribute("code");
    	int count = 0;
    	if(sessStatus == 0){
    		if(loginName != null){
    			user = userService.getUserByLoginName(loginName);
    			if(user != null){
    				count = 1;
    			}
    		}
    		if(code != null){
    			user = userService.getUserByCode(code);
    			if(user != null){
    				count = 1;
    			}
    		}
    	}else{
    		if(loginName != null){
    			if(loginName.equals(sessLoginName)){
    				count = 0;
    			}else if(loginName != sessLoginName){
    				user = userService.getUserByLoginName(loginName);
    				if(user != null){
        				count = 1;
        			}
    			}
    		}
    		if(code != null){
    			if(code.equals(sessCode)){
    				count = 0;
    			}else if(code != sessCode){
    				user = userService.getUserByCode(code);
    				if(user != null){
        				count = 1;
        			}
    			}
    		}
    	}
		
    	tableData = new JSONObject();
			if(count == 1){
				tableData.put("error","该编号已经被使用");
			}else{
				tableData.put("ok","该编号可以使用");
			}
		return SUCCESS;		
	}
	
    //用户明细
	public String userInfo() {
		try {
			user = userService.getUserById(id);
			userWeb = passUserWeb(user);
			branchOfficeList = branchOfficeService.listBranchOffice(null);
		} catch (Exception e) {
			e.printStackTrace();
			getSession().setAttribute("e", e.getMessage());
			return "sysError";
		}
		return SUCCESS;
	}
 
	//修改页面
	public String toModifyUser() {
		try {
			user = userService.getUserById(id);
			getSession().setAttribute("opteStatus", 1);
			getSession().setAttribute("loginName", user.getLoginName());
			getSession().setAttribute("code", user.getCode());
			branchOfficeList = branchOfficeService.listBranchOffice(null);
		} catch (Exception e) {
			e.printStackTrace();
			return "sysError";
		}
		
		return SUCCESS;
	}

	//修改用户
	public String modifyUser() {
			if (user == null) {
				user = userService.getUserById(id);
			}
			user.setModifyTime(new Date());
			userService.modifyUser(user);
					
			uote = new UserOperate();
			uote.setOptePerson(loginUser.getName());
			uote.setOpteGenre(UserOperate.OpteGenre.getValue("修改"));
			uote.setUserCode(user.getCode());
			uote.setUserName(user.getName());
			uote.setOpteTime(new Date());
			useropteService.insertUserOpte(uote);
			operationResult = "success";
			getSession().setAttribute("tip", "修改成功");			
		return SUCCESS;
	}
    //单个删除
	public String deleteUser() {

			user = userService.getUserById(id);
			
			uote = new UserOperate();
			uote.setOptePerson(loginUser.getName());
			uote.setOpteGenre(UserOperate.OpteGenre.getValue("删除"));
			uote.setUserCode(user.getCode());
			uote.setUserName(user.getName());
			uote.setOpteTime(new Date());
			useropteService.insertUserOpte(uote);
			
			user.setModifyTime(new Date());
			user.setStatus(User.Status.Deleted.getValue());
			userService.modifyUser(user);
			operationResult = "success";
		return SUCCESS;
	}
    //批量删除
	public String deleteUserBatch() {
           
			if(ArrayUtils.isEmpty(ids)){
				getSession().setAttribute("tip", "请选择需要删除的信息");	
			}else{			
				for (Long idd : ids) {
					user = userService.getUserById(idd);
					
					uote = new UserOperate();
					uote.setOptePerson(loginUser.getName());
					uote.setOpteGenre(UserOperate.OpteGenre.getValue("删除"));
					uote.setUserCode(user.getCode());
					uote.setUserName(user.getName());
					uote.setOpteTime(new Date());
					useropteService.insertUserOpte(uote);
					
					user.setModifyTime(new Date());
					user.setStatus(User.Status.Deleted.getValue());
				    userService.modifyUser(user);				   
				    getSession().setAttribute("tip", "删除成功");							
			      } 
			  }
		return SUCCESS;
	}

	//用户列表界面数据加载
		public String ajaxListUserData() {
			userList = userService.listUser(queryName, role, start, length,addTime1,addTime2);
			Integer recordsTotal = userService.listUser(queryName, role, null, null,null,null).size();
			tableData = new JSONObject();
			JSONArray userJsonArr = new JSONArray();
			for (User user : userList) {
				JSONObject userJSON = new JSONObject();
				userJSON.put("id", user.getId());
				userJSON.put("name", user.getName());
				userJSON.put("role", User.Role.getEnum(user.getRole(), null, null).name());
				userJSON.put("status", User.Status.getEnum(user.getStatus(), null, null).name());
				userJSON.put("addedTime", new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss").format(user.getAddedTime()));
				userJSON.put("Office", user.getOffice().getName());
				userJsonArr.add(userJSON);
			}
			tableData.put("draw", draw);
			tableData.put("recordsTotal", recordsTotal);
			tableData.put("data", userJsonArr);
			tableData.put("recordsFiltered", recordsTotal);
			return SUCCESS;
		}
		
	//用户信息批量添加
	public String addUserBatch() {
		try {
			if(!(fileName.endsWith("csv") || fileName.endsWith("xls")) ){
				getSession().setAttribute("tip", "失败，目前仅支持csv和xsl格式");
			}else{
				List<List<String>> lls = new ArrayList<>();
				if(fileName.endsWith("csv")){
					InputStream fs = new FileInputStream(file);
					InputStreamReader fsr = new InputStreamReader(fs, "GBK");
					lls = CsvUtil.readCSVFile(fsr);
				}else{
					lls = XlsUtil.readXLSFile(file,0);
				}
				
				userList = userService.listUser(null, null, null, null,null,null);				
				int k = 0;
				for (int i = 1; i < lls.size(); i++) {
					List<String> ls = lls.get(i);
					int count = 0 ;
					for (int j = 0; j < userList.size(); j++) {
						if(userList.get(j).getLoginName().equals(ls.get(1)) || userList.get(j).getCode().equals(ls.get(4))){
							count++;
							break;
						}
					}
					k = count;
					getSession().setAttribute("tip", "录入失败");
				}
			if(k == 0){
				for (int i = 1; i < lls.size(); i++) {
					User newUser = new User();
					List<String> ls = lls.get(i);

					//姓名
					if (ls.get(0) != null && !ls.get(0).equals("")) {					
						newUser.setName(ls.get(0));
					}
					//登录账号
					if (ls.get(1) != null && !ls.get(1).equals("")) {
						newUser.setPassword(ls.get(1));
					}
					//密码
					if (ls.get(2) != null && !ls.get(2).equals("")) {
						newUser.setPassword(ls.get(2));
					}
					//角色
					if(ls.get(3) != null && !ls.get(3).equals("")){
						newUser.setRole(User.Role.getEnum(null, null, ls.get(3)).getValue());
					}
					//编号
					if (ls.get(4) != null && !ls.get(4).equals("")) {
						newUser.setCode(ls.get(4));
					}
					//部门
					if (ls.get(5) != null && !ls.get(5).equals("")) {
						newUser.setDepartment(ls.get(5));
					}			
					// 公司
					if (ls.get(6) != null && !ls.get(6).equals("")) {
						BranchOffice Office = branchOfficeService.getBranchOfficeByName(ls.get(6));
						if (Office != null) {
							newUser.setBranchOffice(Office.getId());						
						}
					}							
					newUser.setStatus(User.Status.Normal.getValue());
					newUser.setAddedTime(new Date());
					newUser.setModifyTime(new Date());
					userService.addUser(newUser);
					
					uote = new UserOperate();
					uote.setOptePerson(loginUser.getName());
					uote.setOpteGenre(UserOperate.OpteGenre.getValue("添加"));
					uote.setUserCode(newUser.getCode());
					uote.setUserName(newUser.getName());
					uote.setOpteTime(new Date());
					useropteService.insertUserOpte(uote);
					getSession().setAttribute("tip", "录入成功");
				  }		
			}
		
			}			
		} catch (Exception e) {
			e.printStackTrace();
			return "sysError";
		}
		return SUCCESS;
	}


	//用户信息导出
	public String exportUserExcel() {	
		try {
			List<User> assetList = userService.listUser(null, null, null, null,null,null);
			String excelName = "用户信息表";
			Workbook wb = getUserExcel(assetList, excelName);
			OutputStream out = getResponse().getOutputStream();
			wb.write(out);
			out.flush();
			out.close();
		} catch (Exception e) {			
			e.printStackTrace();
			getSession().setAttribute("tip", "导出Excel失败");
			getSession().setAttribute("e", e.getMessage());
			return "sysError";
		}
		return null;
	}

	//用户信息导出方法，供上面调用
	private Workbook getUserExcel(List<User> userList, String excelName) throws Exception {
		
			List<String> listTitle = new ArrayList<String>();
			listTitle.add("用户名");
			listTitle.add("用户编号");
			listTitle.add("登录账号");
			listTitle.add("角色");
			listTitle.add("状态");
			listTitle.add("所属部门");
			listTitle.add("所属公司");
			listTitle.add("添加时间");
			listTitle.add("备注");		
			Object[] oarr = listTitle.toArray();
			// HttpServletResponse response = ServletActionContext.getResponse();
			getResponse().setContentType("application/vnd.ms-excel;charset=UTF-8");
			if (getRequest().getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0)// firefox浏览器
				// 转码防止乱码
				excelName = new String(excelName.getBytes("UTF-8"), "ISO8859-1");
			else if (getRequest().getHeader("User-Agent").toLowerCase().indexOf("trident") > 0)// IE浏览器，ie11后请求头中的User-Agent中不再有"MSIE"
				excelName = URLEncoder.encode(excelName, "UTF-8");
			else if (getRequest().getHeader("User-Agent").toLowerCase().indexOf("chrome") > 0)// google浏览器			
				excelName = new String(excelName.getBytes("UTF-8"), "ISO8859-1");
			
			getResponse().addHeader("Content-Disposition", "attachment;filename=" + excelName + ".xls");
			List<POIExcelBaseBean> listRows = new ArrayList<POIExcelBaseBean>();
			SimpleDateFormat fd1 = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
			for (User a : userList) {
				String name = "";
				String code = "";
				String loginName = "";
				String role = "";
				String status = "";
				String depart = "";
				String office = "";
				String addedTime = "";
				String remark = "";
				
				if (a.getName() != null) {
					name = a.getName();
				}
				if (a.getCode() != null){
					code = a.getCode();
				}
				if (a.getLoginName() != null){
					loginName = a.getLoginName();
				}
				if (a.getRole() != null) {
					role = User.Role.getEnum(a.getRole(), null, null).getZhName();
				}			
				if (a.getStatus() != null) {				
					status = User.Status.getEnum(a.getStatus(), null, null).getZhName();
				}
				if (a.getDepartment() != null){				
					depart = a.getDepartment();
				if (a.getBranchOffice() != null){
					BranchOffice branchOffice = branchOfficeService.getBranchOffice(a.getBranchOffice());
					office = branchOffice.getName();
				}
				if (a.getAddedTime() != null) {
					addedTime = fd1.format(a.getAddedTime());
				}
	            remark = a.getRemark();
				listRows.add(new POIExcelUserBean(name, code, loginName, role, status, depart, office, addedTime, remark));
			}		
		  }
			return POIExcelUtils.OutputExcel(oarr, listRows, 1, null, null);
	}
	
	//查询部门
	public String listDepartmentArr1() {
		departmentList = departService.listDepart(departQueryName);
		departmentArr = new JSONArray();
		for (Department department : departmentList) {
			if (departQueryName == null) {
				if (department.getName().contains("_") == false) {
					departmentArr.add(department);
				}
			} else {
				String parent_[] = departQueryName.split("_");
				String chird_[] = department.getName().split("_");
				if (parent_.length == chird_.length - 1) {
					departmentArr.add(department);
				}
			}
		}
		return SUCCESS;
	}

	// getDepartTree
	public String listDepartmentArr() {
		departmentList = departService.listDepart(null);
		departmentArr = new JSONArray();
		for (int i = 4; i >= 2; i--) {
			Map<String, String> releationShip = getDepartmentBy(i, departmentList, departmentArr);
			departmentArr = createNode(releationShip, departmentArr);
		}
		for (Department department : departmentList) {
			List<Department> departmentSingleList = departService.listDepart(department.getName());
			if (departmentSingleList.size() == 1 && !departmentSingleList.get(0).getName().contains("_")) {
				JSONObject departmentJson = new JSONObject();
				departmentJson.put("name", department.getName());
				departmentArr.add(departmentJson);
			}
		}
		return SUCCESS;
	}
	// 依据层次结构获取，得到父级目录以及子目录的对应关系，产生 key和value的键值对,并且找到孩子节点
	private Map<String, String> getDepartmentBy(int level, List<Department> departments, JSONArray childNode) {
		Map<String, String> fiterDepartments = new HashMap<String, String>();
		for (Department department : departments) {
			String[] ss = department.getName().split("_");
			if (ss.length >= level) {
				boolean flag = false;
				// 1.孩子节点和上级节点的关系
				fiterDepartments.put(ss[level - 1], ss[level - 2]);
				for (Object obj : childNode) {
					// 如果已经构建的树是上一级的子节点，则把子节点和父节点的关系联系起来
					JSONObject node = (JSONObject) obj;
					if (node.getString("name").equals(ss[level - 1])) {
						// JSONObject parentNode = new JSONObject();
						// parentNode.put("name",ss[level-1]);
						// parentNode.put("children",);
						flag = true;
					}
				}
				// 2.如果上一级的节点中不存在，该节点，则在孩子节点中新增节点
				if (flag == false) {
					JSONObject cObj = new JSONObject();
					cObj.put("name", ss[level - 1]);
					childNode.add(cObj);
				}
			}
		}
		return fiterDepartments;
	}

	private JSONArray createNode(Map<String, String> filiation, JSONArray children) {
		JSONArray nodes = new JSONArray();
		Set<String> parentString = new HashSet<String>();
		// 获取父节点
		for (String fv : filiation.values()) {
			parentString.add(fv);
		}
		// 将父节点和子节点进行对应
		for (String p : parentString) {
			JSONObject parentNode = new JSONObject();
			parentNode.put("name", p);
			JSONArray child = new JSONArray();
			Set set = filiation.entrySet();
			Iterator it = set.iterator();
			while (it.hasNext()) {
				Map.Entry entry = (Map.Entry) it.next();
				if (entry.getValue().equals(p)) {
					// 将子节点装入的父节点下
					for (Object c : children) {
						JSONObject cObj = (JSONObject) c;
						String name = cObj.getString("name");
						if (entry.getKey().equals(name)) {
							child.add(c);
						}
					}
					// 装入子节点
					if (child.size() > 0) {
						parentNode.put("children", child);
					}
				}
			}
			nodes.add(parentNode);
		}
		return nodes;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}
	
	public UserWeb getUserWeb() {
		return userWeb;
	}

	public void setUserWeb(UserWeb userWeb) {
		this.userWeb = userWeb;
	}

	public UserOperate getUote() {
		return uote;
	}

	public void setUote(UserOperate uote) {
		this.uote = uote;
	}

	public User getLoginUser() {
		return loginUser;
	}

	public void setLoginUser(User loginUser) {
		this.loginUser = loginUser;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Short getRole() {
		return role;
	}

	public void setRole(Short role) {
		this.role = role;
	}

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public Integer getBranchOfficeId() {
		return branchOfficeId;
	}

	public void setBranchOfficeId(Integer branchOfficeId) {
		this.branchOfficeId = branchOfficeId;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public Long[] getIds() {
		return ids;
	}

	public void setIds(Long[] ids) {
		this.ids = ids;
	}

	public String getUserRoleKey() {
		return userRoleKey;
	}

	public void setUserRoleKey(String userRoleKey) {
		this.userRoleKey = userRoleKey;
	}

	public String getUserStatusKey() {
		return userStatusKey;
	}

	public void setUserStatusKey(String userStatusKey) {
		this.userStatusKey = userStatusKey;
	}

	public String getOpera() {
		return opera;
	}

	public void setOpera(String opera) {
		this.opera = opera;
	}

	public List<User> getUserList() {
		return userList;
	}

	public void setUserList(List<User> userList) {
		this.userList = userList;
	}

	public JSONObject getTableData() {
		return tableData;
	}

	public void setTableData(JSONObject tableData) {
		this.tableData = tableData;
	}

	public JSONArray getDepartmentArr() {
		return departmentArr;
	}

	public void setDepartmentArr(JSONArray departmentArr) {
		this.departmentArr = departmentArr;
	}

	public String getDepartQueryName() {
		return departQueryName;
	}

	public void setDepartQueryName(String departQueryName) {
		this.departQueryName = departQueryName;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getQueryName() {
		return queryName;
	}

	public void setQueryName(String queryName) {
		this.queryName = queryName;
	}

	public Integer getDraw() {
		return draw;
	}

	public void setDraw(Integer draw) {
		this.draw = draw;
	}

	public Integer getLength() {
		return length;
	}

	public void setLength(Integer length) {
		this.length = length;
	}

	public Integer getStart() {
		return start;
	}

	public void setStart(Integer start) {
		this.start = start;
	}

	public Date getAddTime1() {
		return addTime1;
	}

	public void setAddTime1(Date addTime1) {
		this.addTime1 = addTime1;
	}

	public Date getAddTime2() {
		return addTime2;
	}

	public void setAddTime2(Date addTime2) {
		this.addTime2 = addTime2;
	}

	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	public String getOperationResult() {
		return operationResult;
	}

	public void setOperationResult(String operationResult) {
		this.operationResult = operationResult;
	}

	public List<BranchOffice> getBranchOfficeList() {
		return branchOfficeList;
	}

	public void setBranchOfficeList(List<BranchOffice> branchOfficeList) {
		this.branchOfficeList = branchOfficeList;
	}

	public List<Department> getDepartmentList() {
		return departmentList;
	}

	public void setDepartmentList(List<Department> departmentList) {
		this.departmentList = departmentList;
	}
}
